home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Delphi 2.0 - Programmer's Utilities Power Pack
/
Delphi 2.0 Programmer's Utilities Power Pack.iso
/
a_to_d
/
dwsock11
/
dwinsock.pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
1996-09-15
|
22KB
|
904 lines
{--------------------------------------------------------------
WinSock component for Borland Delphi.
(C) 1995 by Ulf S÷derberg, ulfs@sysinno.se
History
V1.0 950404 US First release.
Parts of this code was inspired by WINSOCK.PAS by Marc B. Manza.
---------------------------------------------------------------}
unit DWinSock;
interface
uses
SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
Forms, Dialogs;
const
CM_SOCKMSG = WM_USER+1;
MAXCONN = 16; { allow 16 clients for TServerSockets }
{$I winsock.inc }
{$I winsock.if }
type
{ DWinSock exception type }
ESockError = class(Exception);
TSocket = class; { Forward declaration }
{ Socket info codes }
TSockInfo = (siLookUp, siConnect, siListen, siRecv, siSend);
{ Define notification events for socket controls. }
TSockInfoEvent = procedure (Sender : TObject; icode : TSockInfo) of object;
TClientEvent = TNotifyEvent;
TServerEvent = procedure (Sender : TObject; cid : integer) of object;
{ TSockCtrl -- socket control component base class. }
TSockCtrl = class(TCustomControl)
private
{ Event handler references }
FOnInfo : TSockInfoEvent;
{ Design tim connection info }
FHost : string;
FAddress : string;
FService : string;
FPort : u_short;
{ Run time connection info }
FConn : TSocket;
{ Design time bitmap }
FPicture : TBitmap;
{ Access functions }
procedure SetService(const s : string);
procedure SetHost(const n : string);
procedure SetAddress(const a : string);
procedure SetPort(p : u_short);
{ Returns the WinSock.DLL description }
function GetDescription : string;
protected
{ Protected declarations }
constructor Create(AOwner : TComponent); override;
destructor Destroy; override;
procedure Paint; override;
procedure OnSizeChanged(var Message : TWMSize); message WM_SIZE;
public
{ Public declarations }
procedure Info(icode : TSockInfo);
function LocalHost : string;
function Reverse(var a : string) : string;
property Conn : TSocket read FConn;
property Description : string read GetDescription;
published
{ Published declarations }
property Address : string read FAddress write SetAddress;
property Port : u_short read FPort write SetPort;
property Service : string read FService write SetService;
property OnInfo : TSockInfoEvent read FOnInfo write FOnInfo;
end;
{ Definition of the TClientSocket component class }
TClientSocket = class(TSockCtrl)
private
{ Event handler references }
FOnConnect : TClientEvent;
FOnDisconnect : TClientEvent;
FOnRead : TClientEvent;
FOnWrite : TClientEvent;
protected
{ Protected declarations }
procedure OnSockMsg(var Message : TMessage); message CM_SOCKMSG;
public
{ Public declarations }
procedure Open;
procedure Close;
function SendBuf(var buf; cnt : integer) : integer;
function RecvBuf(var buf; cnt : integer) : integer;
function GetBytesSent : integer;
function RecvText : string;
procedure SendText(const s : string);
property BytesSent : integer read GetBytesSent;
property Text : string read RecvText write SendText;
published
{ Published declarations }
constructor Create(AOwner : TComponent); override;
destructor Destroy; override;
property Host : string read FHost write SetHost;
property OnConnect : TClientEvent read FOnConnect write FOnConnect;
property OnDisconnect : TClientEvent read FOnDisconnect write FOnDisconnect;
property OnRead : TClientEvent read FOnRead write FOnRead;
property OnWrite : TClientEvent read FOnWrite write FOnWrite;
property OnInfo;
end;
{ Definition of the TServerSocket component class }
TServerSocket = class(TSockCtrl)
private
{ Event handler references }
FOnAccept : TServerEvent;
FOnDisconnect : TServerEvent;
FOnRead : TServerEvent;
FOnWrite : TServerEvent;
FConns : array [1..MAXCONN] of TSocket;
function GetClient(cid : integer) : TSocket;
function DoAccept : integer;
protected
{ Protected declarations }
procedure OnSockMsg(var Message : TMessage); message CM_SOCKMSG;
public
{ Public declarations }
constructor Create(AOwner : TComponent); override;
destructor Destroy; override;
procedure Listen(nqlen : integer);
procedure Close;
{ Return client socket }
property Client[cid : integer] : TSocket read GetClient; default;
published
{ Published declarations }
property OnAccept : TServerEvent read FOnAccept write FOnAccept;
property OnDisconnect : TServerEvent read FOnDisconnect write FOnDisconnect;
property OnRead : TServerEvent read FOnRead write FOnRead;
property OnWrite : TServerEvent read FOnWrite write FOnWrite;
property OnInfo;
end;
{ TSocket -- socket api wrapper class. }
TSocket = class(TObject)
public
FParent : TSockCtrl; { socket owner }
FSocket : TSock; { socket id }
FAddr : sockaddr_in; { host address }
FConnected : boolean;
FBytesSent : integer; { bytes sent by last SendBuf call }
constructor Create(AParent : TSockCtrl);
destructor Destroy;
function LookupName(var name : string) : in_addr;
function LookupService(var service : string) : u_short;
procedure FillSocket(var name, addr, service : string; var port : u_short);
function LocalAddress : string;
function LocalPort : integer;
function RemoteHost : string;
function RemoteAddress : string;
function RemotePort : integer;
procedure Listen(var name, addr, service : string; port : u_short; nqlen : integer);
procedure Open(var name, addr, service : string; port : u_short);
procedure Close;
function SendBuf(var buf; cnt : integer) : integer;
function RecvBuf(var buf; cnt : integer) : integer;
function RecvText : string;
procedure SendText(const s : string);
property BytesSent : integer read FBytesSent;
property Text : string read RecvText write SendText;
end;
procedure Register;
implementation
{$R DWINSOCK}
var
ExitSave : Pointer;
bStarted : boolean;
nUsers : integer;
nWSErr : integer;
myVerReqd : word;
myWSAData : WSADATA;
{$I ERROR.INC}
{ StartUp -- See if a Windows Socket DLL is present on the system. }
procedure StartUp;
begin
if bStarted then exit;
nUsers := 0;
myVerReqd:=$0101;
nWSErr := WSAStartup(myVerReqd,@myWSAData);
if nWSErr = 0 then
bStarted := true
else
raise ESockError.Create('Can''t startup WinSock');
end;
{ CleanUp -- Tell Windows Socket DLL we don't need its services any longer. }
procedure CleanUp; far;
begin
ExitProc := ExitSave;
if bStarted then
begin
nWSErr := WSACleanup;
bStarted := false;
end;
end;
{--------------------------------------------------------------
TSocket implementation
--------------------------------------------------------------}
constructor TSocket.Create(AParent : TSockCtrl);
begin
inherited Create;
FParent := AParent;
FSocket := INVALID_SOCKET;
FAddr.sin_family := PF_INET;
FAddr.sin_addr.s_addr := INADDR_ANY;
FAddr.sin_port := 0;
FConnected := false;
FBytesSent := 0;
end;
destructor TSocket.Destroy;
begin
if FConnected {or (FSocket <> INVALID_SOCKET)} then
CloseSocket(FSocket);
inherited Destroy;
end;
{ LocalAddress -- get local address }
function TSocket.LocalAddress : string;
var
sa : sockaddr_in;
nl : integer;
begin
Result := '';
if FSocket = INVALID_SOCKET then exit;
if getsockname(FSocket, PSockaddr(@sa), @nl) = 0 then
Result := StrPas(inet_ntoa(sa.sin_addr));
end;
{ LocalPort -- get local port number }
function TSocket.LocalPort : integer;
var
sa : sockaddr_in;
nl : integer;
begin
Result := 0;
if FSocket = INVALID_SOCKET then exit;
if getsockname(FSocket, PSockaddr(@sa), @nl) = 0 then
Result := ntohs(sa.sin_port);
end;
{ RemoteHost -- get name of connected remote host }
function TSocket.Remote